package menu

import (
	"community-service/cmd/api/internal/models/model"
	"context"
	"fmt"
	"gorm.io/gorm"

	"community-service/cmd/api/internal/svc"
	"community-service/cmd/api/internal/types"
	e "community-service/pkg/errorx"
	"google.golang.org/grpc/codes"

	"github.com/zeromicro/go-zero/core/logx"
)

type ListMenuLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewListMenuLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListMenuLogic {
	return &ListMenuLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *ListMenuLogic) ListMenu(req *types.MenuReq) (*types.MenuList, error) {
	var resp types.MenuList
	query := l.svcCtx.DB.WithContext(l.ctx).Model(&model.CsCommunityMenu{}).
		Joins(fmt.Sprintf("LEFT JOIN %s topic ON topic.menu_id = cs_community_menu.id", model.TableNameCsCommunityTopic)).
		Group("cs_community_menu.id")

	// 按名称模糊搜索
	if req.Name != "" {
		query.Where("cs_community_menu.name like ?", "%"+req.Name+"%")
	}

	// 统计

	if err := query.Session(&gorm.Session{}).Where("publish = ?", types.MenuStatusPublish).Count(&resp.PublishCount).Error; err != nil {
		return nil, e.NewGrpcErr(codes.Internal, e.DBError)
	}

	if err := query.Session(&gorm.Session{}).Where("publish = ?", types.MenuStatusUnPublish).Count(&resp.UnPublishCount).Error; err != nil {
		return nil, e.NewGrpcErr(codes.Internal, e.DBError)
	}

	if err := query.Count(&resp.Total).Error; err != nil {
		return nil, e.NewGrpcErr(codes.Internal, e.DBError)
	}

	if req.Type != types.MenuStatusAll {
		query.Where("publish = ?", req.Type == types.MenuStatusPublish)
	}

	// 查询数据和总数
	if err := query.Select(
		"cs_community_menu.*",
		"COUNT(topic.id) topic_count",
	).Order("cs_community_menu.id ASC").Find(&resp.Data).Error; err != nil {
		return nil, e.NewGrpcErr(codes.Internal, e.DBError)
	}

	for _, menu := range resp.Data {
		if err := l.svcCtx.DB.WithContext(l.ctx).Model(&model.CsCommunityTopic{}).
			Joins("topic").
			Joins(fmt.Sprintf("LEFT JOIN %s post ON post.topic_id = topic.id", model.TableNameCsCommunityPost)).
			Select("topic.*", "COUNT(post.id) post_count", "SUM(post.view_count) view_count").
			Group("topic.id").
			Order("topic.id ASC").
			Where("menu_id = ?", menu.Id).Find(&menu.Topics).Error; err != nil {
			return nil, e.NewGrpcErr(codes.Internal, e.DBError)
		}

	}

	return &resp, nil
}
